=begin pod

=TITLE role Iterable

=SUBTITLE Interface for container objects that can be iterated over

    role Iterable { }

C<Iterable> serves as an API for objects that can be iterated with the
C<for> construct and related iteration constructs, like hyper operators.

C<Iterable> objects nested in other C<Iterable> objects (but not within scalar
containers) flatten in certain contexts, for example when passed to a slurpy
parameter (C<*@a>), or on explicit calls to C<flat>.

Its important aspect is a method stub for C<iterator>.

    role DNA does Iterable {
        method iterator(){ self.comb.iterator }
    };

    my @a does DNA = 'GAATCC';
    .say for @a; # OUTPUT: «G␤A␤A␤T␤C␤C␤»

=head1 Methods

=head2 method iterator

Defined as:

    method iterator(--> Iterator:D)

Method stub that ensures all classes doing the C<Iterable> role have a method
C<iterator>.

It is supposed to return an L<Iterator|/type/Iterator>.

    say (1..10).iterator;

=head2 method flat

Defined as:

    method flat(--> Iterable)

Returns another L<Iterable> that flattens out all iterables that the first one
returns.

For example

    say (<a b>, 'c').elems;         # OUTPUT: «2␤»
    say (<a b>, 'c').flat.elems;    # OUTPUT: «3␤»

because C<< <a b> >> is a L<List|/type/List> and thus iterable, so
C<< (<a b>, 'c').flat >> returns C<('a', 'b', 'c')>, which has three elems.

Note that the flattening is recursive, so C<((("a", "b"), "c"), "d").flat>
returns C<("a", "b", "c", "d")>, but it does not flatten itemized sublists:

    say ($('a', 'b'), 'c').perl;    # OUTPUT: «($("a", "b"), "c")␤»

=head2 method lazy

Defined as:

    method lazy(--> Iterable)

Returns a lazy iterable wrapping the invocant.

    say (1 ... 1000).is-lazy;      # OUTPUT: «False␤»
    say (1 ... 1000).lazy.is-lazy; # OUTPUT: «True␤»

=head2 method hyper

Defined as:

    method hyper(Int(Cool) :$batch = 64, Int(Cool) :$degree = 4 --> Iterable)

B«L<More information|https://6guts.wordpress.com/2017/03/16/considering-hyperrace-semantics/>»

Returns another Iterable that is potentially iterated in parallel, with a
given batch size and degree of parallelism.

The order of elements is preserved.

    say ([1..100].hyper.map({ $_ +1 }).list);

=head2 method race

Defined as:

    method race(Int(Cool) :$batch = 64, Int(Cool) :$degree = 4 --> Iterable)

B«L<More information|https://6guts.wordpress.com/2017/03/16/considering-hyperrace-semantics/>»

Returns another Iterable that is potentially iterated in parallel, with a
given batch size and degree of parallelism (number of parallel workers).

Unlike C<hyper>, C<race> does not preserve the order of elements.

    say ([1..100].race.map({ $_ +1 }).list);

=end pod

# vim: expandtab softtabstop=4 shiftwidth=4 ft=perl6
